﻿namespace UsefulTools.Switches
{
    using System.Collections.Generic;

    public static class FunctionalExt
    {
       
      

        public static SwitchIntoSelector<R> SwitchInto<R>(R obj)
        {
            return new SwitchIntoSelector<R>();
        }

        public static Switch<T> Switch<T>(T obj)
        {
            return new Switch<T>(obj);
        }

        public static ValuedSwitch<T, R> ValuedSwitch<T, R>(T obj)
        {
            return new ValuedSwitch<T, R>(obj);
        }

        public static ValuedTypeSwitch<R> ValuedTypeSwitch<R>(object obj)
        {
            return new ValuedTypeSwitch<R>(obj);
        }

        public static TypeSwitch TypeSwitch<T>(T obj)
        {
            return new TypeSwitch(obj);
        }


        public static ValuedSwitch<T, R> From<T,R>(this SwitchIntoSelector<R> obj, T from)
        {
            return new ValuedSwitch<T, R>(from);
        }
        public static ValuedSwitch<T, R> Into<T, R>(this SwitchFromSelector<T> obj)
        {
            return new ValuedSwitch<T, R>(obj.From);
        }

        /// <summary>
        /// Provides a way to switch on multiple values. Each case may control what value to return if any 
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <typeparam name="R"></typeparam>
        /// <param name="obj"></param>
        /// <param name="from"></param>
        /// <returns></returns>
        public static CollectiveSwitch<T, R> AsCascadingCollectiveOf<T, R>(this SwitchIntoSelector<R> obj, IEnumerable<T> from)
        {
            return new CollectiveSwitch<T, R>(from);
        }
        public static ValuedTypeSwitch<R> FromTypeOf<R>(this SwitchIntoSelector<R> sel, object obj)
        {
            return new ValuedTypeSwitch<R>(obj);
        }

    }
    public static class Switch
    {
        public static SwitchFromSelector<T> From<T>(T from)
        {
            return new SwitchFromSelector<T>(from);
        }
        public static SwitchIntoSelector<R> Into<R>()
        {
            return new SwitchIntoSelector<R>();
        }
        public static Switch<T> On<T>(T obj)
        {
            return new Switch<T>(obj);
        }

    }

    public class SwitchIntoSelector<T>
    {
    
    }
    public class SwitchFromSelector<T>
    {
        private readonly T _from;

        public SwitchFromSelector(T @from)
        {
            _from = @from;
        }

        internal T From
        {
            get { return _from; }
        }
    }



}